/**
 * 用户管理
 * @type {{}}
 */

var http = require("request");
var OTTRefreshConfig = require('../../config/refresh');
var bcrypt = require('bcrypt');
var authConfig = require("../../config/auth");
var authorization = require("../services/Authorization");

(function() {
    var UserController = {};
    var root = this;

    function validApplyOTTServiceSession(next) {
        if (!request.appCode || request.appCode == "") return next('appCode is not input or empty');

        if (!request.username || request.username == "") return next('username is not input or empty');

        return next(null,request);
    };

    function getTocken(next)
    {
        var outReq = http.defaults({jar: true})
        root.outReq = outReq;

        var appId = authConfig.appId;
        var appSecret = authConfig.appSecret;
        var date = new Date();
        var timestamp = date.getTime();

        var url = 'http://'+OTTRefreshConfig.ottservice_host + ":"+ OTTRefreshConfig.ottservice_port + '/accessToken';
        var params = [];
        params.push(appId);
        var code = authorization.encrypt(params, appSecret, timestamp);
        var paramsJson = {
            "grantType":"application",
            "appId": appId,
            "timestamp": timestamp,
            "authorization": code
        };
        var jsonStr = JSON.stringify(paramsJson);
        sails.log.debug('AccessTokenAuth.getTocken try to request url:', url,',body:',jsonStr);
        outReq.post({url: url, body: jsonStr}, function (e, r, body) {

            if (e || r.statusCode != 200) {
                sails.log.debug('AccessTokenAuth.getTocken failed,statusCode:', r.statusCode,',body:',body);
                next({"status": 500, "result": "server error"});
                return;
            }

            var rJson = JSON.parse(body);
            sails.log.debug('AccessTokenAuth.getTocken', rJson);
            if (rJson.status == 403) {
                next({"status": 403, "result": "auth failure"});
                return;
            } else if (rJson.status == 200) {
                next(null, rJson);
            } else if (rJson.status == 404) {
                next({"status": 404, "result": "AccessToken is not exist!"});
            } else {
                next({"status": 500, "result": "server error"});
                return;
            }

        });

    }

    function secure(rJson ,next)
    {

        var appId = authConfig.appId;
        var appSecret = authConfig.appSecret;
        var date = new Date();
        var timestamp = date.getTime();

        var url = 'http://'+OTTRefreshConfig.ottservice_host + ":"+ OTTRefreshConfig.ottservice_port + '/secure'

        var params = [];
        params.push(appId);
        var code = authorization.encrypt(params, appSecret, timestamp);

        var paramsJson = {
            "accessToken": rJson.result.access_token,
            "appId": appId,
            "timestamp": timestamp,
            "authorization": code
        };

        var jsonStr = JSON.stringify(paramsJson);
        sails.log.debug('AccessTokenAuth.secure try to request url:', url,',body:',jsonStr);
        outReq.post({url: url, body: jsonStr}, function (e, r, body) {
            if (e || r.statusCode != 200) {
                sails.log.debug('AccessTokenAuth.secure failed,statusCode:', r.statusCode,',body:',body);
                next({"status": 500, "result": "server error"});
                return;
            }
            var rJson = JSON.parse(body);
            sails.log.debug('AccessTokenAuth.login', rJson);
            if (rJson.status == 403) {
                next({"status": 403, "result": "auth failure"});
                return;
            } else if (rJson.status == 200) {
                next(null, rJson);
            } else if (rJson.status == 404) {
                next({"status": 404, "result": "AccessToken is not exist!"});
            } else {
                next({"status": 500, "result": "server error"});
                return;
            }

        });
    }



    function synUser(user, next) {

        if (!user.appCode || user.appCode == "") return next('appCode is not input or empty');

        if (!user.username || user.username == "") return next('username is not input or empty');

        async.waterfall([
            getTocken,
            secure
        ], function(err, result) {
            if (err) {
                sails.log.error('UserController auth failed', err);
                next("connect to OTTRefresh session service failed" + err);
            }
            else
            {
                var url = 'http://'+OTTRefreshConfig.ottservice_host + ":"+ OTTRefreshConfig.ottservice_port + '/user/syncUser';
                var body = {};
                body.username = user.username;
                body.appCode = user.appCode;
                body.sourceId = user.username;
                var jsonStr = JSON.stringify(body);
                sails.log.debug('AccessTokenAuth.synUser try to request url:', url,',body:',jsonStr);
                outReq.post({url:url, body:jsonStr}, function (err, response, body) {
                    if(err){
                        sails.log.error('UserController.synUser', err);
                        next("connect to OTTRefresh session service failed" + err);
                    }
                    else if (response.statusCode != 200)
                    {
                        next("OTTRefresh session service return failed status code:" + response.statusCode);
                    }
                    else
                    {
                        try{
                            var newSession = JSON.parse(body);
                            if (newSession.status != 200)
                            {
                                sails.log.error('UserController.synUser', 'rcv one failed response :' + body);
                                next(newSession);
                            }
                            else
                            {
                                next(null, user);
                            }

                        }catch(e){
                            next("invalid resp from OTTRefresh session service :" + body);
                        }
                    }
                });
            }

        });
    };

    function getAccessCode(user, next) {

        if (!user.appCode || user.appCode == "") return next('appCode is not input or empty');

        if (!user.username || user.username == "") return next('username is not input or empty');

        var url = 'http://'+OTTRefreshConfig.ottservice_host + ":"+ OTTRefreshConfig.ottservice_port + '/getAccessCode'
        var body = {};
        body.username = user.username;
        body.appCode = user.appCode;
        var jsonStr = JSON.stringify(body);
        sails.log.debug('AccessTokenAuth.synUser try to request url:', url,',body:',jsonStr);
        outReq.post({url:url, body:jsonStr}, function (err, response, body) {
            if(err){
                sails.log.error('UserController.getAccessCode', err);
                next("connect to OTTRefresh session service failed" + err);
            }
            else if (response.statusCode != 200)
            {
                next("OTTRefresh session service return failed status code:" + response.statusCode);
            }
            else
            {
                try{
                    var newSession = JSON.parse(body);
                    if (newSession.status != 200)
                    {
                        sails.log.error('UserController.getAccessCode', 'rcv one failed response :' + body);
                        next(newSession);
                    }
                    else
                    {
                        user.accessCode = newSession.result.accessCode;
                        user.ttl = newSession.result.ttl;
                        sails.log.debug('UserController.refreshSession', 'rcv one success response :' + body);

                        next(null, user);
                    }

                }catch(e){
                    next("invalid resp from OTTRefresh session service :" + body);
                }
            }
        });
    };

    function checkNewSesion(user, next)
    {
        if (!user.accessCode || user.accessCode == "") return next('accessCode from OTTRefresh session service  is empty');
        if (!user.ttl ||  user.ttl < 0) return next('ttl from OTTRefresh session service  is invalid:' + user.ttl);

        var now = new Date();
        var deadlineTime = now.getTime() + user.ttl*1000;
        var nextDate = new Date();
        nextDate.setTime(deadlineTime);
        user.deadline = nextDate;

        return next(null, user);
    }

    function saveUser(user, next)
    {
        User.findOne({username:user.username, appCode:user.appCode}).exec(
            function(err, result) {
                if (err) {
                    sails.log.error('UserController.saveUser', err);
                    return next(err);
                }
                else
                {
                    if (result)
                    {
                        User.update({username:user.username, appCode:user.appCode}, user).exec(function(err, results) {
                            if (err) {
                                sails.log.error('UserController.saveUser', err);
                                return next(err);
                            }
                            var result = results[0];
                            sails.log.debug('UserController.saveUser', 'updated user :' + JSON.stringify(result));
                            if (_.has(result, 'id')) {
                                return next(null, result);
                            } else {
                                return next('更新User不存在!');
                            }
                        });
                    }
                    else
                    {
                        User.create(root.request)
                        .exec(function(err, result) {
                            if (err) {
                                sails.log.error('UserController.saveUser', err);
                                return next(err);
                            }
                            return next(null, result);
                        });
                    }
                }
            });
    }

    UserController.applyOTTServiceSession = function(req,res){
        root.request = req.body;
        async.waterfall([
            validApplyOTTServiceSession,
            synUser,
            getAccessCode,
            checkNewSesion,
            saveUser
        ], function(err, result) {
            if (err) {
                if (_.has(err, 'status')) {
                    return res.jsonResponse(err.status, err);
                } else {
                    return res.jsonResponse(400, err);
                }
            }
            return res.jsonResponse(200, result);
        });
    }
    module.exports = UserController;
}())